Q
I'm experiencing problems with some of my big sfnt fonts (> 128k).
Text in these fonts often gets rendered in Geneva, or not at all. Do you
know something about this?
A
Yes, unfortunately. If a sfnt resource is bigger than 128k, the
FontManager does not load it entirely, but only in pieces (as required by
the TrueType scaler) via ReadPartialResource calls. For performance
reasons, the TrueType scaler uses a cache for the font fragments, which gets allocated
in the System heap at boot time. Before MacOS 8.0, the cache size was 10k, which appeared
to be enough for the TrueType fonts known at the time when the cache size was determined
(and when TrueType fonts wanted to be supported on Macintoshes with 2MB of RAM). Meanwhile,
sfnt fonts became more sophisticated, and their tables bigger and bigger,
and 10k just is not enough any more. Since MacOS 8.0, the cache size is 48k; but this still
may not be enough for very special fonts (e.g., sfnts for 2-byte scripts, when
WorldScript II is not installed). Fortunately, there is a way to fix the problem and change
the size of the sfnt fragment cache. Ideally, this should happen as soon as possible
at system startup; so you may want to use the code below inside a little
extension that does the work.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// File: FontFix.c
//
// Calls InitializePartialFonts() with a more reasonable size.
//
// kMinimalPartialFontZoneSize in the system used to be 10 * 1024,
// which is not enough.
// On a system where the PartialFontZone already is big enough,
// InitializePartialFonts() doesn't do anything.
// Only if the existing PartialFontZone is smaller than our new
// kMinimalPartialFontZoneSize (or if there is none), the InitializePartialFonts
// routine allocates and initializes a new one, and properly disposes
// of the previous one (if there was one).
#include <Types.h>
#include <ConditionalMacros.h>
#include <Resources.h>
enum { kMinimalPartialFontZoneSize = 0x0000C000, // 48K
kMaximalPartialFontZoneSize = 0x00080000 // 512K
};
extern pascal OSErr InitializePartialFonts (UInt32 partialFontZoneSize)
THREEWORDINLINE(0x303C, 0x000F, 0xA854);
//-------------------------------------------
void main(void)
{
UInt32 size = kMinimalPartialFontZoneSize; // default
Handle h;
// Debugger();
h = GetResource('pfcs', 0);
if (h != NULL)
{
size = **(UInt32**)h;
if (size < kMinimalPartialFontZoneSize)
size = kMinimalPartialFontZoneSize;
else if (size > kMaximalPartialFontZoneSize)
size = kMaximalPartialFontZoneSize;
}
(void)InitializePartialFonts(size);
}
[Apr 12 1998]
|